package android.slc.box.core.utils

import cn.hutool.core.io.FileUtil
import cn.hutool.core.io.file.FileNameUtil
import cn.hutool.core.util.StrUtil
import cn.hutool.system.SystemUtil
import org.apache.commons.lang3.StringUtils
import org.apache.commons.lang3.SystemUtils
import java.awt.SystemColor.desktop
import java.io.File
import java.util.*
import javax.swing.filechooser.FileSystemView

/**
 * window系统的快捷方式工具类
 *
 * @constructor Create empty Short cut utils
 */
object ShortCutUtils {

    /**
     * 创建快捷方式
     *
     * @param lnkFile 快捷文件
     * @param sourceFile 源文件
     */
    fun createShortCut(sourceFile: String, isCover: Boolean = true): File? {
        if (!SystemUtil.getOsInfo().isWindows) {
            println("当前系统不是window系统,无法创建快捷方式!!")
            return null
        }
        val sourceFileParent: String = FileUtil.getParent(sourceFile, 1)
        val sourceFileName: String = FileNameUtil.getPrefix(sourceFile)
        val linkFile = FileUtil.file(sourceFileParent, "$sourceFileName.lnk")
        if (!isCover && linkFile.exists()) {
            return linkFile
        }
        try {
            linkFile.appendBytes(headFile)
            linkFile.appendBytes(fileAttributes)
            linkFile.appendBytes(fixedValueOne)
            linkFile.appendBytes(sourceFile.toCharArray()[0].toString().toByteArray())
            linkFile.appendBytes(fixedValueTwo)
            linkFile.appendBytes(sourceFile.substring(3).toByteArray(charset("gbk")))
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return linkFile
    }

    /**
     * 创建快捷方式
     *
     * @param sourceFile 源文件
     */
    fun createShortCut(sourceFile: File, isCover: Boolean = true): File? {
        return createShortCut(sourceFile.absolutePath, isCover)
    }

    /**
     * 设置软件开机启动
     *
     * @param sourceFile 源文件
     */
    fun createAppStartup(sourceFile: File, isCover: Boolean = true): File? {
        val lnkFile = createShortCut(sourceFile, isCover)
        lnkFile?.let {
            try {
                val startUpFile = File(startup, "${sourceFile.nameWithoutExtension}.lnk")
                if (isCover || !startUpFile.exists()) {
                    //复制到启动文件夹,若快捷方式已存在则覆盖原来的
                    lnkFile.copyTo(startUpFile, true)
                    //删除缓存的快捷方式
                    lnkFile.delete()
                }
                return if (startUpFile.exists()) {
                    startUpFile
                } else {
                    null
                }
            } catch (e: Exception) {
                return null
            }
        }
        return null
    }

    /**
     * 设置软件开机启动
     *
     * @param sourceFile 源文件路径
     */
    fun createAppStartup(sourceFile: String, isCover: Boolean = true): File? {
        return createAppStartup(File(sourceFile), isCover)
    }

    /**
     * 设置软件桌面快捷方式
     *
     * @param sourceFile 源文件路径
     */
    fun createDesktopShortCut(sourceFile: File, desktopShortCutName: String, isCover: Boolean = true): File? {
        val lnkFile = createShortCut(sourceFile, isCover)
        lnkFile?.let {
            try {
                val startUpFile = File(desktop, "${desktopShortCutName}.lnk")
                if (isCover || !startUpFile.exists()) {
                    //复制到启动文件夹,若快捷方式已存在则覆盖原来的
                    lnkFile.copyTo(startUpFile, true)
                    //删除缓存的快捷方式
                    lnkFile.delete()
                }
                return if (startUpFile.exists()) {
                    startUpFile
                } else {
                    null
                }
            } catch (e: Exception) {
                return null
            }
        }
        return null
    }

    /**
     * 设置软件桌面快捷方式
     *
     * @param sourceFile 源文件路径
     */
    fun createDesktopShortCut(sourceFile: String, desktopShortCutName: String, isCover: Boolean = true): File? {
        return createDesktopShortCut(File(sourceFile), desktopShortCutName, isCover)
    }

    /**
     * 设置软件桌面快捷方式
     *
     * @param sourceFile 源文件路径
     */
    fun createDesktopShortCut(sourceFile: File, isCover: Boolean = true): File? {
        return createDesktopShortCut(sourceFile, sourceFile.nameWithoutExtension, isCover)
    }

    /**
     * 设置软件桌面快捷方式
     *
     * @param sourceFile 源文件路径
     */
    fun createDesktopShortCut(sourceFile: String, isCover: Boolean = true): File? {
        val sourceFileTemp = File(sourceFile)
        return createDesktopShortCut(sourceFileTemp, sourceFileTemp.nameWithoutExtension, isCover)
    }

    /**
     * 开机启动目录
     */
    val startup =
        "${System.getProperty("user.home")}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\"

    /**
     * 桌面目录
     */
    val desktop = FileSystemView.getFileSystemView().homeDirectory.absolutePath + "\\"

    /**
     * 文件头，固定字段
     */
    private val headFile = byteArrayOf(
        0x4c, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
        0xc0.toByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46
    )

    /**
     * 文件头属性
     */
    private val fileAttributes = byteArrayOf(
        0x93.toByte(), 0x00, 0x08, 0x00,  //可选文件属性
        0x20, 0x00, 0x00, 0x00,  //目标文件属性
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //文件创建时间
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //文件修改时间
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //文件最后一次访问时间
        0x00, 0x00, 0x00, 0x00,  //文件长度
        0x00, 0x00, 0x00, 0x00,  //自定义图标个数
        0x01, 0x00, 0x00, 0x00,  //打开时窗口状态
        0x00, 0x00, 0x00, 0x00,  //热键
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //未知
    )

    private val fixedValueOne = byteArrayOf(
        0x83.toByte(), 0x00, 0x14, 0x00, 0x1F, 0x50, 0xE0.toByte(), 0x4F, 0xD0.toByte(),
        0x20, 0xEA.toByte(), 0x3A, 0x69, 0x10, 0xA2.toByte(),
        0xD8.toByte(), 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D.toByte(), 0x19, 0x00, 0x2f
    )

    /**
     * 固定字段2
     */
    private val fixedValueTwo = byteArrayOf(
        0x3A, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00,
        0x32, 0x00, 0x04, 0x00, 0x00, 0x00, 0x67, 0x50, 0x91.toByte(), 0x3C, 0x20, 0x00
    )

}